/***************************************************************************
 *   Copyright (C) 2008 by						   *
 *          Ali Abdou							   *
 *          Camille Gallet						   *
 *          Rémy Hubscher						   *
 *          Regis Strub							   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#include "Board.hpp"
#include "math.h"
Board * Board::instance=NULL;
 

Board::Board(QWidget * parent)
	: QWidget(parent)
{
    QGridLayout *layout = new QGridLayout;
    
    for(int i = 0; i < 9; i++)
    {
        cells[i] = new Cellule();
        cells[i]->setId(i);
        layout->addWidget(cells[i],i/3,i%3,Qt::AlignCenter);
        QObject::connect(cells[i],SIGNAL(rightClick()),this,SLOT(moveValidated()));
        QObject::connect(cells[i],SIGNAL(leftClick(Cellule*)),this,SLOT(unselect(Cellule*)));
    }
    setLayout(layout);
}

Board::~Board(){
    for(int i = 0; i < 9; i++)
    {
        delete cells[i];
    }
}

// Singleton
Board * Board::getInstance()
{
	if(!instance)
	    instance = new Board();
	return instance;
}

void Board::setBoard(GameEngine::box * b)
{

    for(int i = 0; i < 9; i++)
    {
	QString t = QString("%1").arg((int)b[i]);
            cells[i]->setValue(b[i]);
            board[i] = b[i];
    }
}

GameEngine::box * Board::getBoard()
{
    return board;
}

Cellule *Board::getSelectedCellule(){
    Cellule *tmp;
    for(int i; i < 9; i++)
    {
        if(cells[i]->getSelected()){
            tmp = cells[i];
            break;
        }
    }
    return tmp;
}

void Board::moveValidated(){
	bool cv = false;
    Cellule *tmpC1 = NULL;
    Cellule *tmpC2 = NULL;
    
    for(int i = 0; i < 9; i++){
        if(cells[i]->getSelected() == 1)
            {tmpC1 = this->cells[i];
			 move.setFrom(i);}
        else if(cells[i]->getSelected() == 2)
            {tmpC2 = this->cells[i];
             move.setTo(i);
            }
    }
    move.setKind(typeOfMove(tmpC1, tmpC2));
    emit valideCoup(cv, move, this->board);
   // QMessageBox::information(NULL,"Validite du coup",QString("Coup :%1\nType :%2\nDe :%3\nA :%4").arg(cv).arg(move.getKind()).arg(move.getFrom()).arg(move.getTo()));
    
    this->resetSelected();
    if(cv == true)
    	emit sendMoving(move);
    else
    	QMessageBox::information(NULL,"Validite du coup","Coup invalide \n On ne triche pas !!!");	

}

Moving::kind Board::typeOfMove(Cellule *c1, Cellule *c2){

	//deplacement horizontal
	Moving::kind type;
	
	if(c1 == NULL && c2 != NULL && c2->getValue() == GameEngine::SQUARE_ONLY){//deplacement vertical
		//si on n'a pas cliqu� avec le bouton droit --> pose d'un pion
		//QMessageBox::information(NULL,"Mvt","PutChecker")
		type = Moving::PUT_CHECKER;
	}
	else if(c1 != NULL)
		 if((c1->getValue() == GameEngine::SQUARE_ONLY || c1->getValue() == GameEngine::SQUARE_RED || c1->getValue() == GameEngine::SQUARE_BLUE)&& c2->getValue() == GameEngine::EMPTY){
		//si la premiere case n'est pas vide, mais la seconde si ==> deplacement de case
		//QMessageBox::information(NULL,"Mvt","Move");
		//QMessageBox::information(NULL,"m3",QString("%1").arg(type));		
		if(c1->getId()/3 == c2->getId()/3){
				//deplacement horizontal
				
				//deplacement unique
				if(fabs(c1->getId()%3 - (c2->getId()%3)) == 1){
					type = Moving::MOVE_SQUARE;
				}else
			
				//deplacement double
				if(fabs(c1->getId()%3 - c2->getId()%3) == 2){
					type = Moving::MOVE_DOUBLE_SQUARE;
				}
			
		}else if(c1->getId()%3 == c2->getId()%3){//deplacement vertical
				//deplacement unique

				if(fabs((int)c1->getId()/3 - (int)((c2->getId()/3)))==1){
						type = Moving::MOVE_SQUARE;

				}else
			
				//deplacement double
				if(fabs(c1->getId()/3 - (c2->getId()/3))==2){
				type = Moving::MOVE_DOUBLE_SQUARE;
				}
		}
   	}else if(c1->getValue() == GameEngine::SQUARE_RED || c1->getValue() == GameEngine::SQUARE_BLUE){
		//si la premiere case contient un pion ==> deplacement de pion
		//si la case du pions n'est pas eloignée dedeux case horizontalement et verticalement
		//donc le deplacement n'est possible que d'une case
		type = Moving::MOVE_CHECKER;
		if(fabs(c2->getId()/3-c1->getId()/3)<2 && fabs(c2->getId()%3-c1->getId()%3)<2){
			type = Moving::MOVE_CHECKER;
		}
	}

    return type;
}


Moving Board::getMove(){
   return move;
}

void Board::getCell(int i, Cellule* c){
   if (i>=0 && i<9)
     c=cells[i];
}


void Board::resetSelected(){
		for(int i =0; i<9;i++)
				this->cells[i]->setSelected(0);	
}


void Board::setConnect(bool b){
	if(b == true){
		for(int i=0; i<9; i++){
			QObject::disconnect((QObject *)cells[i],SIGNAL(rightClick()),this,SLOT(moveValidated()));
		}
	}else{
		for(int i=0; i<9; i++){
			QObject::connect((QObject *)cells[i],SIGNAL(rightClick()),this,SLOT(moveValidated()));
		}
	}
}

void Board::unselect(Cellule* exept){
	for(int i=0; i < 9;i++){
		if(this->cells[i]->getId() != exept->getId()){
			cells[i]->setSelected(0);
		}
	}
}
